package com.itheima.web.shiro;

import com.itheima.domain.system.Module;
import com.itheima.domain.system.User;
import com.itheima.service.system.impl.ModuleServiceImpl;
import com.itheima.service.system.impl.UserServiceImpl;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class AuthRealm extends AuthorizingRealm {

    @Autowired
    private UserServiceImpl userService;
    @Autowired
    private ModuleServiceImpl moduleService;

    /**
     * 授权   把认证成功的权限储存起来
     * @param principals
     * @return
     * @see SimpleAuthorizationInfo
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //获取认证成功的用户信息
        User user = (User) principals.fromRealm(this.getName()).iterator().next();
        //获取当前用户的模块信息
        List<Module> moduleList = moduleService.findModuleByUser(user);
        //创建用户封装用户权限名称的集合
        Set<String> permissions = new HashSet<>();
        //遍历用户的模块集合
        for (Module module : moduleList) {
            permissions.add(module.getName());
        }
        //创建放回值对象
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(permissions);
        //放回
        return info;
    }

    /**
     * 认证
     * @param token
     * @return 认证的信息，包含查询出来的用户登录信息，和用户登录的凭证，每个用户自己的安全域名称
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //把token转为UsernamePasswordToken
        UsernamePasswordToken uToken = (UsernamePasswordToken) token;
        //取出邮箱和密码
        String email = uToken.getUsername();
        String password = new String(uToken.getPassword(),0,uToken.getPassword().length);

        //使用用户名去数据库查数据
        User user = userService.findByEmail(email);
        //判断用户名是否存在
        if(user!=null){

            //创建方法返回值对象
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
            return info;
        }
        //返回null时，shiro会抛出异常
        return null;
    }
}
